#include "log_common.h"

using namespace fsl;
using namespace std;

//bool g_log_file_lock = false;

std::fstream tstamp;

static void getTimeString(char *time_str, uint32_t str_max_len)
{
    time_t t_now;
    time(&t_now);
    struct tm *local;

    local = localtime(&t_now);
    strftime(time_str, 100, "%Y/%m/%d %H:%M:%S: ", local);
}


/*FUNCTION*********************************************************************
 *
 * Function Name : getIllegalUID
 * Description   : Function replaces any illegal characters like '?', '\\', '/', '.' or ':',
 * with REP_CHR(defined in server_log.h) and adds an extension name '.log\0'.
 *END*************************************************************************/
static void getIllegalUID(char *res, const char *UID)
{
    strcpy(res, UID);
    /* Replace all illegal chars */
    while (*res != '\0')
    {
        if (*res == '?' || *res == '\\' || *res == '/' ||
            *res == '.' || *res == ':')
                *res = REP_CHR;
        res++;
    }
    strcat(res, LOG_EXT);
}

LogStream::LogStream()
{
    this->log_file = new char[strlen(LOG_INIT_NAME) + 1];
    strcpy(this->log_file, LOG_INIT_NAME);
    this->busy = false;
    this->file_only = true;
}

LogStream::LogStream(const char *UID)
{
    char *log_file_name = new char[strlen(UID) + strlen(LOG_EXT) + 1]; /* allocated for "UID.ext" */
    char *full_file_name = new char[strlen(LOG_DIR) + strlen(UID) +\
                                    strlen(LOG_EXT) + 1]; /* allocated for ".\log\UID.ext" */

    /* Make full path as .\log\UID.log */
    getIllegalUID(log_file_name, UID);
    strcpy(full_file_name, LOG_DIR);
    strcat(full_file_name, log_file_name);

    this->log_file = new char[strlen(LOG_DIR) + strlen(UID) +\
                              strlen(LOG_EXT) + 1]; /* allocated for ".\log\UID.ext" */
    strcpy(this->log_file, full_file_name);

    ofstream f(full_file_name, ofstream::app);

    if (f == NULL) /* First run, make direction */
        mkdir(LOG_DIR);
    else
        f.close();

    delete log_file_name;
    delete full_file_name;
    this->busy = false;
    this->file_only = true;
}

LogStream & LogStream::operator << (const char c)
{
    while (busy == true);
    busy = true;

    ofstream f(this->log_file, std::ofstream::app);
    if(!f) return *this;

    f << c ;
    f.close();
    if (!this->file_only) cout<<c;
    busy = false;

    return *this;
}

LogStream & LogStream::operator << (const int8_t i)
{
    while (busy == true);
    busy = true;

    ofstream f(this->log_file, std::ofstream::app);
    if(!f) return *this;

    f << i ;
    f.close();
    if (!this->file_only) cout<<i;
    busy = false;

    return *this;
}

LogStream & LogStream::operator << (const int16_t i)
{
    while (busy == true);
    busy = true;

    ofstream f(this->log_file, std::ofstream::app);
    if(!f) return *this;

    f << i ;
    f.close();
    if (!this->file_only) cout<<i;
    busy = false;

    return *this;
}

LogStream & LogStream::operator << (const int32_t i)
{
    while (busy == true);
    busy = true;

    ofstream f(this->log_file, std::ofstream::app);
    if(!f) return *this;

    f << i ;
    f.close();
    if (!this->file_only) cout<<i;
    busy = false;

    return *this;
}

LogStream & LogStream::operator << (const uint8_t i)
{
    while (busy == true);
    busy = true;

    ofstream f(this->log_file, std::ofstream::app);
    if(!f) return *this;

    f << i ;
    f.close();
    if (!this->file_only) cout<<i;
    busy = false;

    return *this;
}

LogStream & LogStream::operator << (const uint16_t i)
{
    while (busy == true);
    busy = true;

    ofstream f(this->log_file, std::ofstream::app);
    if(!f) return *this;

    f << i ;
    f.close();
    if (!this->file_only) cout<<i;
    busy = false;

    return *this;
}

LogStream & LogStream::operator << (const uint32_t i)
{
    while (busy == true);
    busy = true;

    ofstream f(this->log_file, std::ofstream::app);
    if(!f) return *this;

    f << i ;
    f.close();
    if (!this->file_only) cout<<i;
    busy = false;

    return *this;
}

LogStream & LogStream::operator << (const float ff)
{
    while (busy == true);
    busy = true;

    ofstream f(this->log_file, std::ofstream::app);
    if(!f) return *this;

    f << ff ;
    f.close();
    if (!this->file_only) cout<<ff;
    busy = false;

    return *this;
}

LogStream & LogStream::operator << (const double ff)
{
    while (busy == true);
    busy = true;

    ofstream f(this->log_file, std::ofstream::app);
    if(!f) return *this;

    f << ff ;
    f.close();
    if (!this->file_only) cout<<ff;
    busy = false;

    return *this;
}

LogStream & LogStream::operator << (const char *s)
{
    while (busy == true);
    busy = true;

    ofstream f(this->log_file, std::ofstream::app);
    if(!f) return *this;
    f << s;
    f.close();
    if (!this->file_only) cout<<s;
    busy = false;

    return *this;
}

LogStream & LogStream::operator << (fstream &fs)
{
    if (fs != tstamp) return *this;

    while (busy == true);
    busy = true;

    ofstream f(this->log_file, std::ofstream::app);
    if(!f) return *this;

#if SHOW_TIME == 1
    char *time_str = new char[128];
    getTimeString(time_str, 128);
    f << time_str;
    if (!this->file_only) cout<<time_str;
    delete time_str;
#endif
    f.close();

    busy = false;

    return *this;
}

void dispTime()
{
#if SHOW_TIME == 1
    char *time_str = new char[128];
    getTimeString(time_str, 128);
    cout << time_str;
    delete time_str;
#endif

}
/*EOF*/
